#light

open System.IO

type Block (path: string) =
    let contents =
        Seq.generate_using
            (fun () -> File.OpenText(path))
            (fun reader -> 
                if reader.EndOfStream then None
                else Some(reader.ReadLine()) )
    member b.getIndexKeys() =
        contents
        |> Seq.map(fun x -> x.Split([|' '|]).[0])
        |> Seq.mapi(fun i x -> (x, path, i))
    member b.Contains (needle: string) =
        contents
        |> Seq.filter(fun x -> x.Contains(needle))
        
type Index (blocks: seq<Block>) = 
    member i.Items =
        blocks
        |> Seq.map(fun x -> x.getIndexKeys())
        |> Seq.concat
    member i.Create(outpath: string) =
        using(File.CreateText(outpath)) (fun out ->
            i.Items
            |> Seq.sort_by(fun (x, p, i) -> x)
            |> Seq.iter(fun (x, p, i) -> out.WriteLine(x + "\t" + p + "\t" + i.ToString())))
            
type DirectoryIndexBuilder(path: string) =
    let dir = Directory.GetFiles(path)
    let blocks = 
        dir
        |> Seq.map(fun x -> new Block(x))
    member d.Create(outpath: string) = 
        let index = new Index(blocks)
        index.Create(outpath)